package cn.edu.tju.se.records.web;

import java.io.*;
import java.util.List;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import cn.edu.tju.se.base.service.FileManager;
import cn.edu.tju.se.records.domain.Patient;
import cn.edu.tju.se.records.service.PatientService;
import net.coobird.thumbnailator.Thumbnails;

import org.apache.commons.io.FileUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.multipart.MultipartFile;

import com.google.gson.Gson;
import cn.edu.tju.se.base.domain.Message;
import cn.edu.tju.se.base.service.ImgCompress;
import cn.edu.tju.se.base.service.ZipCompressorByAnt;
import cn.edu.tju.se.base.web.controller.BaseController;
import cn.edu.tju.se.records.domain.Photo;
import cn.edu.tju.se.records.service.PhotoService;
import sun.misc.BASE64Decoder;

@Controller
@RequestMapping(value="/photo")
public class PhotoController extends BaseController{

	@Autowired
	PhotoService photoService;

	@Autowired
	PatientService patientService;

	public PatientService getPatientService() {
		return patientService;
	}

	public void setPatientService(PatientService patientService) {
		this.patientService = patientService;
	}

	public PhotoService getPhotoService() {
		return photoService;
	}

	public void setPhotoService(PhotoService photoService) {
		this.photoService = photoService;
	}


	
	@RequestMapping(method=RequestMethod.GET, value="/{id}")	
	public @ResponseBody Photo getPhoto(@PathVariable String id,Model model) {
		return photoService.get(Integer.parseInt(id));
	}
	
	@RequestMapping(method=RequestMethod.POST,value="/patientid/{id}")
	@ResponseStatus(HttpStatus.OK)
	public void addPhoto(@RequestBody String body) {
		Photo photo = (new Gson()).fromJson(body, Photo.class);
		photoService.add(photo);
	}
	
	@RequestMapping(method=RequestMethod.POST, value="/{id}")
	@ResponseStatus(HttpStatus.OK)
	public void updatePhotoByPost(@RequestBody String body) {
		Photo photo = (new Gson()).fromJson(body, Photo.class);
		photoService.update(photo);
	}

	@RequestMapping(method=RequestMethod.POST, value="/edit/{patientid}/{id}")
	@ResponseStatus(HttpStatus.OK)
	public @ResponseBody List<Photo> editPhotoByPost(@RequestBody String body,@PathVariable String patientid,@PathVariable String id) {
		Photo photo = photoService.get(Integer.parseInt(id));
		String imgFilePath = photoService.getImgPath() + photo.getPhotourl();
		BASE64Decoder decoder = new BASE64Decoder();
		try
		{
			//Base64解码String
			String baseBody = body.substring(body.lastIndexOf(",")+1);
			byte[] b = decoder.decodeBuffer(baseBody);
			for(int i=0;i<b.length;++i)
			{
				if(b[i]<0)
				{//调整异常数据
					b[i]+=256;
				}
			}
			//生成jpeg图片
			//新生成的图片
			OutputStream out = new FileOutputStream(imgFilePath);
			out.write(b);
			out.flush();
			out.close();
		}
		catch (Exception e)
		{
			System.out.println(e);
		}
		File oldImg = new File(imgFilePath);
		String newImgPath=oldImg.getParent();
		Long editTag = System.currentTimeMillis();
		String newImgName = editTag+"_edit_"+photo.getPhotostate()+"_"+photo.getPhotoname();
		File newImg=new File(newImgPath+"/"+newImgName);
		if(oldImg.renameTo(newImg))
		{
			System.out.println("修改成功!");
		}
		else
		{
			System.out.println("修改失败");
		}
		String newUrl = "/compress/"+photo.getPatientid()+"/"+photo.getPhotodate()+"/"+photo.getPhototype()+"/"+newImgName;
		photo.setPhotourl(newUrl);
		photoService.update(photo);
		System.out.println(patientid);
		List<Photo> photos = photoService.findPhotoByPatientId(patientid);
		return photos;
	}
	
	@RequestMapping(method=RequestMethod.DELETE, value="/{patientid}/{id}")
	public @ResponseBody List<Photo> removePhoto(@PathVariable String patientid,@PathVariable String id) {

		File photofile = new File(photoService.getImgPath()+ photoService.get(Integer.parseInt(id)).getPhotourl());
		File imagefile = new File(photoService.getImgPath() + photoService.get(Integer.parseInt(id)).getImagesurl());

		if(imagefile.isFile() && imagefile.exists()){
			imagefile.delete();
		}
		if(photofile.isFile() && photofile.exists()){
			photofile.delete();
		}
		photoService.remove(Integer.parseInt(id));
		List<Photo> photos = photoService.findPhotoByPatientId(patientid);
		return photos;	
	}

	@RequestMapping(method=RequestMethod.DELETE, value="/multidelete/date/{patientid}/{date}")
	public @ResponseBody List<Photo> removePhotoByDate(@PathVariable String patientid,@PathVariable String date) {
		photoService.removePhotoFilesbyPhotoDate(patientid,date);
		photoService.removePhotosbyPhotoDate(patientid,date);
		List<Photo> photos = photoService.findPhotoByPatientId(patientid);
		return photos;
	}

	@RequestMapping(method=RequestMethod.DELETE, value="/multidelete/dates/{patientid}")
	public @ResponseBody List<Photo> removePhotoByDates(@PathVariable String patientid,@RequestParam(value = "datelist") List<String> datelist) {
		for (int i = 0;i<datelist.size();i++){
			photoService.removePhotoFilesbyPhotoDate(patientid,datelist.get(i));
			photoService.removePhotosbyPhotoDate(patientid,datelist.get(i));
		}
		List<Photo> photos = photoService.findPhotoByPatientId(patientid);
		return photos;
	}
	
	@RequestMapping(method=RequestMethod.GET, value="/patientid/{id}")
	public @ResponseBody List<Photo> getPhotoByPatientId(@PathVariable String id) {	
		List<Photo> photos = photoService.findPhotoByPatientId(id);
		return photos;
	}
	
	
	@RequestMapping(method=RequestMethod.GET, value="/download/{id}")
	public ResponseEntity<byte[]> download(HttpServletResponse res,HttpServletRequest request,@PathVariable String id) throws IOException{

		String filePath = photoService.getImgPath() + "/upload/"+id;

		String cachePath = photoService.getImgPath() + "/cache/";
		File cacheDir = new File(cachePath);
		if(!cacheDir.exists() && !cacheDir.isDirectory()){
			cacheDir.mkdirs();
		}
		String cacheFilePath = cachePath+id+".zip";
		ZipCompressorByAnt zc = new ZipCompressorByAnt(cacheFilePath);
		zc.compressExe(filePath);

		File file=new File(cacheFilePath);
		HttpHeaders headers = new HttpHeaders();
		headers.setContentDispositionFormData("attachment", new String(file.getName().getBytes("utf-8"), "ISO8859-1"));
		headers.setContentType(MediaType.APPLICATION_OCTET_STREAM);
		return new ResponseEntity<byte[]>(FileUtils.readFileToByteArray(file),
				headers, HttpStatus.CREATED);
	}

	@RequestMapping(method=RequestMethod.GET, value="/download/date/{patientid}/{photodate}")
	public ResponseEntity<byte[]> downloadByDate(HttpServletResponse res,HttpServletRequest request,
												 @PathVariable String patientid,
												 @PathVariable String photodate) throws IOException{
		String filePath = photoService.getImgPath() + "/upload/"+patientid+"/"+photodate;
		String cachePath = photoService.getImgPath() + "/cache/";
		File cacheDir = new File(cachePath);
		if(!cacheDir.exists() && !cacheDir.isDirectory()){
			cacheDir.mkdirs();
		}
		String cacheFilePath = cachePath+patientid+photodate+".zip";
		ZipCompressorByAnt zc = new ZipCompressorByAnt(cacheFilePath);
		zc.compressExe(filePath);

		File file=new File(cacheFilePath);
		HttpHeaders headers = new HttpHeaders();
		headers.setContentDispositionFormData("attachment", new String(file.getName().getBytes("utf-8"), "ISO8859-1"));
		headers.setContentType(MediaType.APPLICATION_OCTET_STREAM);
		return new ResponseEntity<byte[]>(FileUtils.readFileToByteArray(file),
				headers, HttpStatus.CREATED);
	}


	@RequestMapping(method=RequestMethod.GET, value="/download/type/{id}/{phototype}/{photostate}/{photodate}")
	public ResponseEntity<byte[]> downloadSingleState(HttpServletResponse res,HttpServletRequest request,@PathVariable String id,
													  @PathVariable String phototype,
													  @PathVariable String photostate,
													  @PathVariable String photodate) throws IOException{
		//String patientname = patientService.findPatientByPatientId(id).getPatientname();
		String filePath = photoService.getImgPath() + "/upload/"+id+"/"+photodate+"/"+phototype;
		String cachePath = photoService.getImgPath() + "/cache/";
		File cacheDir = new File(cachePath);
		if(!cacheDir.exists() && !cacheDir.isDirectory()){
			cacheDir.mkdirs();
		}
		String cacheFilePath = cachePath+id+photostate+photodate+".zip";
		ZipCompressorByAnt zc = new ZipCompressorByAnt(cacheFilePath);
		zc.compressExe(filePath);

		File file=new File(cacheFilePath);
		HttpHeaders headers = new HttpHeaders();
		headers.setContentDispositionFormData("attachment", new String(file.getName().getBytes("utf-8"), "ISO8859-1"));
		headers.setContentType(MediaType.APPLICATION_OCTET_STREAM);
		return new ResponseEntity<byte[]>(FileUtils.readFileToByteArray(file),
				headers, HttpStatus.CREATED);
	}

	@RequestMapping(method=RequestMethod.GET, value="/download/single/{photoid}")
	public ResponseEntity<byte[]> downloadSinglePic(HttpServletResponse res,HttpServletRequest request,
													 @PathVariable int photoid) throws IOException{
		Photo photo = photoService.get(photoid);
		String filePath = photoService.getImgPath() + photo.getImagesurl();

		File file=new File(filePath);
		HttpHeaders headers = new HttpHeaders();
		headers.setContentDispositionFormData("attachment", new String(file.getName().getBytes("utf-8"), "ISO8859-1"));
		headers.setContentType(MediaType.APPLICATION_OCTET_STREAM);
		return new ResponseEntity<byte[]>(FileUtils.readFileToByteArray(file),
				headers, HttpStatus.CREATED);
	}

	@RequestMapping(value="/upload/cover", method=RequestMethod.POST)
	public @ResponseBody Message handleFileUpload(HttpServletRequest request, @RequestParam(value = "file") MultipartFile file,
												  @RequestParam(value = "patientid") String patientid) throws IOException {
		Message msg = new Message();
		if  (!file.isEmpty()) {
			try{
				String name = file.getOriginalFilename();
                String cachePath = photoService.getImgPath() + "/compress/"+patientid;
				String osFile = cachePath+"/"+patientid+"cover.jpg";
				String caFile = cachePath+"/"+patientid+"cover.jpg";
				File cacheFile = new File(cachePath);
				if(!cacheFile .exists()  && !cacheFile .isDirectory()){
					cacheFile.mkdirs();
				}

				byte[] bytes = file.getBytes();
				BufferedOutputStream stream =
						new BufferedOutputStream(new FileOutputStream(new File(osFile)));
				stream.write(bytes);
				stream.close();

				Thumbnails.of(osFile)
						.size(400, 400)
						.outputFormat("jpg")
						.toFile(caFile);

				Patient patient = patientService.findPatientByPatientId(patientid);
				patient.setCoverphoto("/compress/"+patientid+"/"+patientid+"cover.jpg");
				patientService.update(patient);

				msg.setInfoMessage("上传成功");

				return msg;
			}catch (Exception e){
				return msg;
			}
		}else{
			return msg;
		}
	}

    @RequestMapping(value="/upload", method=RequestMethod.POST)
    public @ResponseBody List<Photo> handleFileUpload(@RequestParam(value = "file") MultipartFile file,
                                                  @RequestParam(value = "phototype") String phototype,
                                                  @RequestParam(value = "photostate") String photostate,
                                                  @RequestParam(value = "photodate") String photodate,
                                                  @RequestParam(value = "patientid") String patientid) throws IOException {
        if  (!file.isEmpty()) {
			try {
				String name = file.getOriginalFilename();
				String prefix = name.substring(name.lastIndexOf(".") + 1);
				String nam = name.substring(0, name.lastIndexOf("."));
				Long editTag = System.currentTimeMillis();
				String filePath = photoService.getImgPath() + "/upload/" + patientid + "/" + photodate + "/" + phototype;
				String cachePath = photoService.getImgPath() + "/compress/" + patientid + "/" + photodate + "/" + phototype;
				String osFile = filePath + "/" + "_" + patientid + "_" + photostate + "_" + editTag + "." + prefix;
				String caFile = cachePath + "/" + "_" + patientid + "_" + photostate + "_" + editTag + "." + "jpg";
				File saveFile = new File(filePath);
				File cacheFile = new File(cachePath);

				if (!saveFile.exists() && !saveFile.isDirectory()) {
					saveFile.mkdirs();
				}
				if (!cacheFile.exists() && !cacheFile.isDirectory()) {
					cacheFile.mkdirs();
				}

				byte[] bytes = file.getBytes();
				BufferedOutputStream stream =
						new BufferedOutputStream(new FileOutputStream(new File(osFile)));
				stream.write(bytes);
				stream.close();

				if (prefix.equals("tif") || prefix.equals("TIF")) {
					ImgCompress imgCom = new ImgCompress();

					imgCom.tifToJpg(osFile, caFile);


//                    Thumbnails.of(caFile)
//                    .size(400, 400)
//                    .outputFormat("jpg")
//                    .toFile(caFile);
				} else {
					Thumbnails.of(osFile)
							.size(400, 400)
							.outputFormat("jpg")
							.toFile(caFile);
				}

				String photourl = "/compress/" + patientid + "/" + photodate + "/" + phototype + "/" + "_" + patientid + "_" + photostate + "_" + editTag + "." + "jpg";

				String imagesurl = "/upload/" + patientid + "/" + photodate + "/" + phototype + "/" + "_" + patientid + "_" + photostate + "_" + editTag + "." + prefix;

				Photo photo = new Photo();
				photo.setPatientid(patientid);
				photo.setPhotodate(photodate);
				photo.setPhotoname(name);
				photo.setPhotostate(photostate);
				photo.setPhototype(phototype);
				photo.setPhotourl(photourl);
				photo.setImagesurl(imagesurl);
				photoService.add(photo);
			}catch(IOException e){
				e.printStackTrace();
			}catch (Exception e){
				e.printStackTrace();
			}
        }
		List<Photo> photos = photoService.findPhotoByPatientId(patientid);
		return photos;
    }
}
